#include "mcu_init.h"
#include "tos_k.h"
#include "mqttclient.h"
#include "cJSON.h"
#include "sal_module_wrapper.h"
#include "mqtt_config.h"
#include "E53_IS1.h"
#include "m26.h"

k_event_t report_result_event;
k_event_flag_t report_success = 1 << 0;
k_event_flag_t report_fail = 1 << 1;

k_sem_t infrared_sem;

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//外部中断回调函数
 {
  if(GPIO_Pin==E53_GPIO2_Pin)//检测是否为红外外部中断
	{
	   tos_sem_post(&infrared_sem);
	}
}

/***************************************************************
* 函数名称: tos_topic_handler
* 说    明: IoT Explorer下行数据处理
***************************************************************/
static void tos_topic_handler(void* client, message_data_t* msg)
{
    cJSON *root;
    cJSON *method;
    cJSON* cjson_status = NULL;
    char* status = NULL;
    k_event_flag_t event_flag = report_fail;

    /* 打印日志 */
    MQTT_LOG_I("-----------------------------------------------------------------------------------");
    MQTT_LOG_I("%s:%d %s()...\ntopic: %s, qos: %d. \nmessage:\n\t%s\n", __FILE__, __LINE__, __FUNCTION__,
            msg->topic_name, msg->message->qos, (char*)msg->message->payload);
    MQTT_LOG_I("-----------------------------------------------------------------------------------\n");

    // 1. 解析从云端收到的控制信息，示例控制信息为
    //"{"method":"control","clientToken":"clientToken-Xx-N_enad","params":{"power_switch":0}}"
    root = cJSON_Parse((char*)msg->message->payload);
    if (root == NULL) {
        printf("report reply message parser fail\r\n");
        cJSON_Delete(root);
        return;
    }

    // 2. 解析出method
    method = cJSON_GetObjectItem(root, "method");
    if (!method) {
        printf("Invalid json method\r\n");
        cJSON_Delete(root);
        return;
    }

    // 3. 解析出数据上报后平台回复的上报状态
    cjson_status = cJSON_GetObjectItem(root, "status");
    if (cjson_status) {
        // 4. 获取上报状态，判断上报成功或失败
        status = cJSON_GetStringValue(cjson_status);
        if (status == NULL) {
            printf("report reply status parser fail\r\n");
            event_flag = report_fail;
        } else {
            if (strstr(status, "success")) {
                event_flag = report_success;
            } else {
                event_flag = report_fail;
            }
        }
        cJSON_Delete(root);
        root = NULL;
        status = NULL;
        // 5. 触发事件
        tos_event_post(&report_result_event, event_flag);
        return;
    }
}

#define REPORT_SENSOR_DATA_TEMPLATE "{\"method\":\"report\",\"clientToken\":\"00000001\",\"params\":{\"infrared_status\":%d}}"
#define CONTROL_REPLY_DATA_TEMPLATE "{\"method\":\"control_reply\",\"clientToken\":\"%s\",\"code\":0,\"status\":\"ok\"}"

char report_buf[200];

/***************************************************************
* 函数名称: mqttclient_task
* 说    明: 主任务，连接平台以及发送上行数据
***************************************************************/
void mqttclient_task(void)
{
    int error;

    mqtt_client_t *client = NULL;

    mqtt_message_t msg;

    k_event_flag_t match_flag;

    int  infrared_status;

    char  host_ip[20];

    memset(&msg, 0, sizeof(msg));

    m26_sal_init(HAL_UART_PORT_0);

    mqtt_log_init();

    client = mqtt_lease();

    tos_event_create(&report_result_event, (k_event_flag_t)0u);
    tos_sem_create(&infrared_sem, (k_sem_cnt_t)5);

    /* Domain Format: <your product ID>.iotcloud.tencentdevices.com */
    tos_sal_module_parse_domain(MQTT_SERVER_DOMAIN, host_ip, sizeof(host_ip));
    /*
        These infomation is generated by mqtt_config_gen.py tool in "TencentOS-tiny\tools" directory.
    */
    mqtt_set_port(client, MQTT_SERVER_PORT);
    mqtt_set_host(client, host_ip);
    mqtt_set_client_id(client, MQTT_CLIENT_ID);
    mqtt_set_user_name(client, MQTT_USR_NAME);
    mqtt_set_password(client, MQTT_PASSWORD);
    mqtt_set_clean_session(client, 1);

    error = mqtt_connect(client);

    MQTT_LOG_D("mqtt connect error is %#0x", error);

    error = mqtt_subscribe(client, MQTT_SUBSCRIBE_TOPIC_DOWN, QOS0, tos_topic_handler);

    MQTT_LOG_D("mqtt subscribe error is %#0x", error);

    while (1) {

        /* 上报传感器数据 */
        tos_sem_pend(&infrared_sem, TOS_TIME_FOREVER);
        infrared_status = E53_IS1_Read_Data();
        if (infrared_status == 1) {
            LCD_ShowCharStr(80, 100, "Alarm   ", WHITE, BLUE, 24);
            E53_IS1_Beep_Set(ON);
        } else {
            LCD_ShowCharStr(80, 100, "Safe   ", WHITE, BLUE, 24);
            E53_IS1_Beep_Set(OFF);
        }
        memset(&msg, 0, sizeof(msg));
        memset(report_buf, 0, sizeof(report_buf));
        snprintf(report_buf, sizeof(report_buf), REPORT_SENSOR_DATA_TEMPLATE, infrared_status);
        msg.qos = QOS0;
        msg.payload = (void *)report_buf;
        error = mqtt_publish(client, MQTT_PUBLISH_TOPIC_UP, &msg);
        MQTT_LOG_D("mqtt publish error is %#0x", error);
        tos_event_pend(&report_result_event,
                       report_success | report_fail,
                       &match_flag,
                       TOS_TIME_FOREVER,
                       TOS_OPT_EVENT_PEND_ANY | TOS_OPT_EVENT_PEND_CLR);

        if (match_flag == report_success) {
            printf("report to Tencent IoT Explorer success\r\n");

        } else if (match_flag == report_fail) {
            printf("report to Tencent IoT Explorer fail\r\n");
        }
        /* END*/
        
    }
}

/***************************************************************
* 函数名称: application_entry
* 说    明: 应用入口
***************************************************************/
void application_entry(void *arg)
{
    E53_IS1_Init();
    mqttclient_task();
    while (1) {
        printf("This is a mqtt demo!\r\n");
        tos_task_delay(1000);
    }
}
